package com.morehair.service.admin.impl;

import com.morehair.bean.pojo.Log;
import com.morehair.bean.vo.admin.Info;
import com.morehair.bean.bo.LoginUser;
import com.morehair.bean.pojo.Admin;
import com.morehair.bean.pojo.AdminExample;
import com.morehair.bean.vo.admin.BaseRespVo;
import com.morehair.config.MallToken;
import com.morehair.mapper.AdminMapper;
import com.morehair.mapper.LogMapper;
import com.morehair.mapper.SystemMapper;
import com.morehair.service.admin.AuthService;
import com.morehair.utils.Md5Util;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.io.Serializable;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

/**
 * Author  kkw
 * Date  2021/6/5 21:45
 * Version 1.0
 * Description :
 */
@Service
@Transactional
public class AuthServiceImpl implements AuthService {
    @Autowired
    AdminMapper adminMapper;
    @Autowired
    LogMapper logMapper;
    @Autowired
    SystemMapper systemMapper;

    @Override
    public BaseRespVo login(LoginUser user) {
        Subject subject = SecurityUtils.getSubject();

        try {
            String password = Md5Util.getMd5(user.getPassword());
            subject.login(new MallToken(user.getUsername(),password,"admin"));
            Serializable id = subject.getSession().getId();
            return BaseRespVo.ok(id);
        } catch (AuthenticationException | NoSuchAlgorithmException e) {
            return BaseRespVo.fail(605,null,"用户帐号或密码不正确");
//            {"errno":605,"errmsg":"用户帐号或密码不正确"}
        }

    }

    @Override
    public Info getInfo(String token) {
        Subject subject = SecurityUtils.getSubject();
        String username = (String) subject.getPrincipal();
        Info info = new Info();
        Admin admin = getAdminByUsername(username);
        Integer[] roleIds = admin.getRoleIds();
        List<String> roles=new ArrayList<>();
        ArrayList<String> permissionList = new ArrayList<>();
        Boolean hasAll=false;
        for (Integer roleId : roleIds) {
            String role=adminMapper.selectRoleByRoleId(roleId);
            roles.add(role);
            if (roleId == 1) {
                hasAll=true;
            }
        }
        info.setRoles(roles);
        info.setAvatar(admin.getAvatar());
        info.setName(username);
        if (hasAll) {
            permissionList.add("*");
            info.setPerms(permissionList);
            return info;
        }
        List<String> permissions = selectPermissionByUsername(username);
        for (String permission : permissions) {
            String s=systemMapper.selectPermissionApiByName(permission);
            permissionList.add(s);
        }
        info.setPerms(permissionList);


        return info;
    }

    @Override
    public List<String> selectPermissionByUsername(String username) {
        List<String> allPermission = new ArrayList<>();
        HashSet<String> permissionSet = new HashSet<>();
        Admin admin = getAdminByUsername(username);
        Integer[] roleIds = admin.getRoleIds();
        for (Integer roleId : roleIds) {
            List<String> permissions= adminMapper.selectPermissionByRoleId(roleId);
            permissionSet.addAll(permissions);
        }
        for (String s : permissionSet) {
            allPermission.add(s);
        }
        System.out.println(allPermission);
        return allPermission;
    }

    @Override
    public void insertLog(String username, String host, int i, String action, int status, String result ,String comment) {
        boolean status1=true;
        if (status!=1){
            status1=false;
        }
        Log log = new Log();
        log.setAdmin(username);
        log.setIp(host);
        log.setType(i);
        log.setAction(action);
        log.setStatus(status1);
        log.setResult(result);
        log.setAddTime(new Date());
        log.setUpdateTime(new Date());
        log.setComment(comment);
        logMapper.insertSelective(log);
    }

    private Admin getAdminByUsername(String username) {
        AdminExample adminExample = new AdminExample();
        AdminExample.Criteria criteria = adminExample.createCriteria();
        criteria.andUsernameEqualTo(username);
        List<Admin> admins = adminMapper.selectByExample(adminExample);
        return admins.get(0);
    }
}
